package com.limao.DBProvider;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Vector;

import com.limao.DBDataClass.DBObjectDataClass;
import com.limao.DbConnection.DbConnectionManager;
import com.limao.Model.LzPluginException;
import com.limao.Tool.CacheClass;

/**
 * 
 * @author zjf 对当个表进行处理 如果查询的的时候有多个表。 请在 getSelectSql() 里面对其他表的字段名 加入 下划线
 * 
 */

public abstract class ObjectProvider {

	private Vector<String> fields;

	protected abstract String getTableName();

	protected abstract String getSelectSql();

	protected String getKeyName() {
		return "id";
	}

	protected abstract String getTable_ide();

	private String getinnerSelectSql() {
		String ssql = getSelectSql();
		if (ssql == null)
			ssql = " select * from " + getTableName() + " tb1 ";
		return ssql;
	}

	public DBObjectDataClass load_byid(int id) {

		String ssql = getinnerSelectSql();
		ssql = ssql + " where id=?";
		DBObjectDataClass tmp = null;
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {

			con = DbConnectionManager.getConnection();
			pstmt = con.prepareStatement(ssql);
			pstmt.setInt(1, id);
			rs = pstmt.executeQuery();
			if (rs.next()) {
				tmp = getDataByRow(rs);
			}

		} catch (Exception e) {
			tmp = null;
			e.printStackTrace();
		} finally {
			DbConnectionManager.closeConnection(rs, pstmt, con);
		}
		return tmp;

	}
	
	public DBObjectDataClass load_byid(int id,PreparedStatement pstmt,Connection con) throws Exception{

		String ssql = getinnerSelectSql();
		ssql = ssql + " where id=?";
		DBObjectDataClass tmp = null;
		ResultSet rs = null;
		DbConnectionManager.fastcloseStmt(rs,pstmt);
		pstmt = con.prepareStatement(ssql);
		pstmt.setInt(1, id);
		rs = pstmt.executeQuery();
		if (rs.next()) {
			tmp = getDataByRow(rs);
		}
		
		DbConnectionManager.closeResultSet(rs);
		return tmp;
	}
	
	public DBObjectDataClass load_byOrder(int orderid, int type, PreparedStatement pstmt,Connection con) throws Exception{

		String ssql = getinnerSelectSql();
		ssql = ssql + " where orderid=? and type=? ";
		DBObjectDataClass tmp = null;
		ResultSet rs = null;
		DbConnectionManager.fastcloseStmt(rs,pstmt);
		pstmt = con.prepareStatement(ssql);
		pstmt.setInt(1, orderid);
		pstmt.setInt(2, type);
		rs = pstmt.executeQuery();
		if (rs.next()) {
			tmp = getDataByRow(rs);
		}
		
		DbConnectionManager.closeResultSet(rs);
		return tmp;
	}

	protected abstract DBObjectDataClass createChildClass();

	protected DBObjectDataClass getDataByRow(ResultSet rs) throws SQLException {
		DBObjectDataClass data = createChildClass();
		ResultSetMetaData rsmd = rs.getMetaData();// rs为查询结果集
		int count = rsmd.getColumnCount();
		for (int i = 1; i <= count; i++) {
			data.put(rsmd.getColumnName(i), CacheClass.getStringValue(rs
					.getObject(rsmd.getColumnName(i))));
		}
		return data;
	}

	public ArrayList<DBObjectDataClass> load_byWhere(String wherestr) {
		String ssql = getinnerSelectSql();
		ssql = ssql + wherestr;

		ArrayList<DBObjectDataClass> result = new ArrayList<DBObjectDataClass>();
		DBObjectDataClass tmp = null;
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {

			con = DbConnectionManager.getConnection();
			pstmt = con.prepareStatement(ssql);
			rs = pstmt.executeQuery();
			while (rs.next()) {
				tmp = getDataByRow(rs);
				result.add(tmp);
			}

		} catch (Exception e) {
			tmp = null;
			e.printStackTrace();
		} finally {
			DbConnectionManager.closeConnection(rs, pstmt, con);
		}
		return result;

	}

	public ArrayList<DBObjectDataClass> load_byids(String idlist) {

		if (idlist.endsWith(","))
			idlist = idlist.substring(0, idlist.length() - 1);
		String wherestr = " where tb1.id in (" + idlist + ")";

		return load_byWhere(wherestr);

	}

	public Vector getBaseFileds() {
		if (fields != null)
			return fields;

		String ssql = getinnerSelectSql();
		ssql = ssql + " where id=0 ";
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {

			con = DbConnectionManager.getConnection();
			pstmt = con.prepareStatement(ssql);
			rs = pstmt.executeQuery();
			fields = getfields(rs);

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DbConnectionManager.closeConnection(rs, pstmt, con);
		}
		return fields;

	}

	protected Vector<String> getfields(ResultSet rs) throws SQLException {
		Vector<String> heads = new Vector<String>();
		ResultSetMetaData rsmd = rs.getMetaData();// rs为查询结果集
		int count = rsmd.getColumnCount();
		for (int i = 1; i <= count; i++) {
			heads.add(rsmd.getColumnName(i));// 把列名存入向量heads中
		}
		//
		return heads;
	}


	public DBObjectDataClass insert(DBObjectDataClass db, PreparedStatement pstmt,
			Connection con) throws Exception {
		boolean isinner = (con != null);
		if ((!(db.containsKey("id") && db.get("id") != null))
				&& getTable_ide() != null) {
			// 生成ID号
			String id = CacheClass.getSYStable_ideCacheManager()
					.get_Table_ide_num(getTable_ide());
			if (id == null)
				return null;
			db.setId(id);
			db.put("id", id);
		}
		String[] insertparam = getInsertSqlparams(db);
		//
		String sql = " insert into " + getTableName() + "(" + insertparam[0]
				+ ") values " + "(" + insertparam[1] + ")";
		boolean abortTransaction = false;

		try {
			if (!isinner) {
				con = DbConnectionManager.getTransactionConnection();
			}

			pstmt = con.prepareStatement(sql);
			pstmt.execute();

		} catch (Exception e) {
			abortTransaction = true;
			e.printStackTrace();
			throw e;
		} finally {
			if (!isinner) {
				DbConnectionManager.closeTransactionConnection(pstmt, con,
						abortTransaction);

			}
		}

		return db;
	}

	public DBObjectDataClass update(DBObjectDataClass db, PreparedStatement pstmt,
			Connection con) throws Exception {
		boolean isinner = (con != null);
		String[] insertparam = getUpdateSqlparams(db);
		String sql = " update " + getTableName() + " set " + insertparam[0]
				+ "  " + insertparam[1] + "";
		boolean abortTransaction = false;

		try {
			if (!isinner)
				con = DbConnectionManager.getTransactionConnection();
			pstmt = con.prepareStatement(sql);
			pstmt.execute();

		} catch (Exception e) {
			abortTransaction = true;
			e.printStackTrace();
			throw e;
		} finally {
			if (!isinner) {
				DbConnectionManager.closeTransactionConnection(pstmt, con,
						abortTransaction);

			}
		}

		return db;

	}

	/**
	 * 
	 * @param db
	 * @return
	 */
	protected String[] getInsertSqlparams(DBObjectDataClass db) {
		String[] result = new String[3];
		String fieldstr = "";
		String valuesstr = "";
		String wherestr = "";
		Vector<String> v = getBaseFileds();

		if (db.containsKey("id")) {
			wherestr = " where id=" + db.get("id");
		}
		for (String field : v) {
			String tmpvalue;
			if (db.containsKey(field)) {
				fieldstr = fieldstr + field + ",";
				tmpvalue = (String) db.get(field);
				if (tmpvalue == null) {
					valuesstr = valuesstr + "null,";
				} else {
					valuesstr = valuesstr + "'" + tmpvalue + "',";
				}
			}

		}

		if (fieldstr.endsWith(","))
			fieldstr = fieldstr.substring(0, fieldstr.length() - 1);

		if (valuesstr.endsWith(","))
			valuesstr = valuesstr.substring(0, valuesstr.length() - 1);

		result[0] = fieldstr;
		result[1] = valuesstr;
		result[2] = wherestr;

		return result;
	}

	protected String[] getUpdateSqlparams(DBObjectDataClass db)
			throws LzPluginException {
		String[] result = new String[2];
		String fieldstr = "";
		String wherestr = "";
		Vector<String> v = getBaseFileds();

		if (db.containsKey("id")) {
			wherestr = " where id=" + db.get("id");
		} else {
			throw new LzPluginException("没有主键信息不能修改");
		}
		for (String field : v) {
			String tmpvalue;
			if (db.containsKey(field)) {
				tmpvalue = (String) db.get(field);
				if (tmpvalue == null) {
					fieldstr = fieldstr + field + "=null,";
				} else {
					fieldstr = fieldstr + field + "='" + tmpvalue + "',";
				}
			}

		}

		if (fieldstr.endsWith(","))
			fieldstr = fieldstr.substring(0, fieldstr.length() - 1);

		result[0] = fieldstr;
		result[1] = wherestr;
		return result;
	}

}
